"use strict";

const Controller = require("egg").Controller;
const crypto = require("crypto");
class UserController extends Controller {
  // 注册
  async reg() {
    let { ctx, app } = this;
    ctx.validate(
      {
        username: { type: "string", required: true,  range: { min: 5, max: 20, }, desc: "用户名", },
        password: { type: "string", required: true, desc: "密码", },
        repassword: { type: "string", required: true, desc: "确认密码", },
      },
      {
        equals: [["password", "repassword"]],
      }
    );
    let { username, password } = ctx.request.body;
    if ( await app.model.User.findOne({ where: { username, }, }) ) {
      ctx.throw(400, "用户名已存在");
    }
    let res = await app.model.User.create({ username, password,status:1,type:0});
    if (!res) {
      ctx.throw(400, "创建用户失败");
    }
    ctx.apiSuccess(res);
  }

  // 登陆
  async login() {
    const { ctx, app } = this; 
    ctx.validate({
      username: { type: "string", required: true, desc: "用户名", },
      password: { type: "string", required: true, desc: "密码", },
    });
    let { username, password } = ctx.request.body;
    // 验证该用户是否存在|验证该用户状态是否启用 
    let user = await app.model.User.findOne({ where: { username, status:1 }, });
    if (!user) {
      ctx.throw(400, "用户不存在或已被禁用");
    }
    // 验证密码
    await this.checkPassword(password, user.password);

    user = JSON.parse(JSON.stringify(user));
    // 生成token
    let token = ctx.getToken(user);
    user.token = token;
    // 加入缓存中
    if (!(await this.service.cache.set("user_" + user.id, token))) {
      ctx.throw(400, "登录失败");
    }
    delete user.password;
    delete user.id;
    delete user.deleted_time;
    delete user.created_time;
    delete user.updated_time;
    // 返回用户信息和token
    return ctx.apiSuccess(user);
  }

  // 退出登录
  async logout() {
    const { ctx, service } = this; 
    let current_user_id = ctx.authUser.id; 
    if (!(await service.cache.remove("user_" + current_user_id))) {
      ctx.throw(400, "退出登录失败");
    }
    ctx.apiSuccess("退出成功");
  }

  // 获取全部用户-分页
  async getUsers() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    let user = await app.model.User.findOne({ where: { id, }, });
    if (!user) {
      ctx.throw(400, "请先登陆");
    }
    let res = await ctx.page( app.model.User, {}, { attributes: ["id", "nickname", "username", "avatar"], } );
    ctx.apiSuccess(res);
  }
  // 获取全部用户-不分页
  async getAllUsers() {
    const { ctx, app } = this;
    let res = await app.model.User.findAll({ order: [['id', 'ASC']] });
    ctx.apiSuccess(res);
  }
  // 获取用户-个人
  async getUserOne() {
    const { ctx, app } = this;
    let id = null
    if (!ctx.query.userId) {
      id = ctx.authUser.id;
    } else {
      id = ctx.query.userId;
    }
    let res = await app.model.User.findOne({
      where: { id, },
      attributes: [ "id", "nickname", "username", "email", "avatar", "phone", "sex", "desc", ],
    });
    if (!res) {
      ctx.throw(400, "获取用户信息失败");
    }
    ctx.apiSuccess(res);
  }

  // 修改用户-个人 https://blog.csdn.net/itbrand/article/details/109239620
  async updateUser() {
    const { ctx, app } = this;  
    ctx.validate({
      userId: { type: "string", required: true, desc: "用户Id" },
      username: { type: "string", required: true, range: { min: 5, max: 20, }, desc: "用户名", },
      nickname: { type: "string", required: false, range: { min: 5, max: 20, }, desc: "昵称", },
      email: { type: "string", required: true, desc: "邮箱", format: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/}, 
      avatar: { type: "string", required: true, desc: "头像", },
      phone: { type: "string", required: true, desc: "手机", format: /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/ },
      sex: { type: "string", required: false, desc: "性别", },
      desc: { type: "string", required: false, desc: "个性签名", },
    });

    /*
    let user = await app.model.User.findOne({ where: { id: ctx.request.body.userId, },
      attributes: [ "id", "nickname", "username", "email", "avatar", "phone", "sex", "desc", ],
    });
    */
    let { userId, username, nickname, email, avatar, phone, sex, desc } = ctx.request.body;
    if(!/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(email)){
      ctx.throw(500, "邮箱格式错误");
    }
    if(!/^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/.test(phone)){
      ctx.throw(500, "手机格式错误");
    }
    let user = await app.model.User.findOne({ where: { id:   ctx.authUser.id }, });
    if (!user) {
      ctx.throw(400, "获取用户信息失败");
    }
    
    let res = await user.update({ id: userId, username, nickname, email, avatar, phone, sex, desc, });
    ctx.apiSuccess(res);
  }

  // 删除用户
  async removeUser() {
    const { ctx, app } = this; 
    const id = ctx.authUser.id;
    if (id == undefined) {
      ctx.throw(400, "请先登陆");
    }
    let userId = ctx.request.body.userId;
    if (!userId) {
      ctx.throw(400, "请填写用户id");
    }
    let user = await app.model.User.findOne({ where: { id: userId, }, });
    if (!user) {
      ctx.throw(400, "该用户不存在");
    }

    let removeUser = await app.model.User.findOne({ where: { id, }, });
    if (!user) {
      ctx.throw(400, "请先登陆");
    }
    let res = await user.destroy({ where: { id: userId, }, });
    if (res) {
      return ctx.apiSuccess("删除成功")
    } else {
      ctx.throw("删除失败")
    }
  }

  // 通过用户id获取该用户权限的菜单路径
  async getMenuByUserId() {
    const { ctx, app } = this;
    // 拿到当前用户id
    let userid = ctx.authUser.id;
    let res = await app.model.User.findOne({ where: { id: userid } })

    let aa = res.nickname.length > 0 ? (res.nickname).split(",") : []
    var bb = []
    var path = []
    if (aa.length > 0) {
      for(let i in aa){
        let role = await app.model.Role.findOne({
          where: {
            id: aa[i]
          }
        })
        bb = bb.concat(bb, (role.menuids).split(","))
      }
    }
    if (bb.length > 0) {
      let menusid = [...new Set(bb)]
      for(let j in menusid){
        let menu = await app.model.Menus.findOne({
          where: {
            id: menusid[j]
          }
        })
        path.push(menu.menupath)
      }
      return ctx.apiSuccess(path)
    }
  }

  async getrole(){}

  // 验证密码
  async checkPassword(password, hash_password) {
    // 先对需要验证的密码进行加密
    const hmac = crypto.createHash("sha256", this.app.config.crypto.secret);
    hmac.update(password);
    password = hmac.digest("hex");
    let res = password === hash_password;
    if (!res) {
      this.ctx.throw(400, "密码错误");
    }
    return true;
  }
}

module.exports = UserController;
